package multiagent

import (
	"anders-cli/internal/ai"
	"anders-cli/internal/config"
	"anders-cli/pkg/logger"
	"context"
	"encoding/json"
	"fmt"
	"sync"
	"time"
)

// ProjectManager 项目管理器 - 团队模式的核心协调者
type ProjectManager struct {
	*BaseAgent
	Agents            []Agent
	TaskLogs          []string
	MaxFeedbackRounds int
	ConflictThreshold int
	mu                sync.RWMutex
}

// FeedbackItem 子Agent反馈项
type FeedbackItem struct {
	AgentName  string
	Output     string
	Confidence int
	Feedback   string
	Importance int // PM评分的重要性分数
}

// NewProjectManager 创建项目管理器
func NewProjectManager(backend ai.Backend, maxRounds, conflictThreshold int) *ProjectManager {
	return &ProjectManager{
		BaseAgent:         NewBaseAgent("PM", "Project Manager - Task Coordinator and Decision Maker", backend),
		Agents:            make([]Agent, 0),
		TaskLogs:          make([]string, 0),
		MaxFeedbackRounds: maxRounds,
		ConflictThreshold: conflictThreshold,
	}
}

// NewProjectManagerWithRules 创建带有角色规则的项目管理器
func NewProjectManagerWithRules(characterName string, backend ai.Backend, maxRounds, conflictThreshold int) (*ProjectManager, error) {
	baseAgent, err := NewBaseAgentWithRules("PM", "pm", characterName, backend)
	if err != nil {
		return nil, err
	}

	return &ProjectManager{
		BaseAgent:         baseAgent,
		Agents:            make([]Agent, 0),
		TaskLogs:          make([]string, 0),
		MaxFeedbackRounds: maxRounds,
		ConflictThreshold: conflictThreshold,
	}, nil
}

// AddAgent 添加子Agent到团队
func (pm *ProjectManager) AddAgent(agent Agent) {
	pm.mu.Lock()
	defer pm.mu.Unlock()
	pm.Agents = append(pm.Agents, agent)
}

// Process 实现Agent接口 - 处理复杂任务的协调流程
func (pm *ProjectManager) Process(task string, context map[string]any) (output string, confidence int, feedback string) {
	// 初始化日志以防nil指针
	pm.initLog()

	logger.Info("[PM] 开始处理任务: %s", task)

	// 1. 任务分解
	subTasks := pm.decomposeTask(task)
	logger.Info("[PM] 任务分解为 %d 个子任务", len(subTasks))

	// 2. 并行分发任务给子Agent
	feedbacks := pm.distributeTasks(subTasks, context)

	// 3. 评分反馈重要度
	feedbacks = pm.scoreFeedbacks(feedbacks, task)

	// 4. 处理冲突和决策
	finalDecision := pm.resolveConflicts(feedbacks)

	// 5. 生成最终输出
	output = pm.generateFinalOutput(finalDecision, task)

	// 6. 收集所有任务日志
	pm.collectTaskLogs()

	confidence = 90 // PM通常有较高置信度
	feedback = pm.generateFeedbackSummary(feedbacks)

	// 更新当前日志
	pm.CurrentLog = &TaskLog{
		TaskID:        pm.generateTaskID(),
		Description:   fmt.Sprintf("Coordinated team processing of: %s", task),
		InputSummary:  fmt.Sprintf("Task: %s, %d agents involved", task, len(pm.Agents)),
		OutputSummary: output[:min(100, len(output))],
		Status:        "completed",
		Confidence:    confidence,
		Feedback:      feedback,
		Timestamp:     time.Now().Unix(),
	}

	return output, confidence, feedback
}

// decomposeTask 任务分解 - 将复杂任务分解为子任务
func (pm *ProjectManager) decomposeTask(task string) []string {
	prompt := fmt.Sprintf(`As Project Manager, decompose this complex task into specific sub-tasks for different specialists:

Task: %s

Available specialists:
- Business Analyst: Requirements analysis, user stories, business logic
- Architect: System design, technical architecture, technology choices

Provide 2-4 specific sub-tasks, one for each specialist. Format as JSON array.`, task)

	response, err := pm.Backend.Query(prompt, nil)
	if err != nil {
		// 降级处理：为每个agent分配通用任务
		subTasks := make([]string, len(pm.Agents))
		for i := range pm.Agents {
			subTasks[i] = fmt.Sprintf("Analyze and provide input for: %s", task)
		}
		return subTasks
	}

	// 解析JSON响应
	var subTasks []string
	if err := json.Unmarshal([]byte(response), &subTasks); err != nil {
		// 如果JSON解析失败，使用简单分割
		subTasks = []string{
			fmt.Sprintf("Business analysis for: %s", task),
			fmt.Sprintf("Technical architecture for: %s", task),
		}
	}

	return subTasks
}

// distributeTasks 并行分发任务给子Agent
func (pm *ProjectManager) distributeTasks(subTasks []string, ctx map[string]any) []FeedbackItem {
	pm.mu.RLock()
	agentCount := len(pm.Agents)
	pm.mu.RUnlock()

	if agentCount == 0 {
		return []FeedbackItem{}
	}

	// 从配置获取超时时间
	cfg := config.Get()
	agentTimeout := time.Duration(cfg.MultiAgent.AgentTimeout) * time.Second
	if agentTimeout <= 0 {
		agentTimeout = 90 * time.Second // 默认90秒
	}

	// 计算总超时时间：MaxFeedbackRounds * AgentTimeout
	totalTimeout := time.Duration(pm.MaxFeedbackRounds) * agentTimeout
	if totalTimeout <= 0 {
		totalTimeout = 90 * time.Second // 默认90秒
	}

	logger.Info("[PM] 使用Agent超时时间: %v, 总超时时间: %v", agentTimeout, totalTimeout)

	// 创建超时上下文
	timeoutCtx, cancel := context.WithTimeout(context.Background(), totalTimeout)
	defer cancel()

	// 创建结果通道
	results := make(chan FeedbackItem, agentCount)

	// 并行处理每个子Agent
	for i, agent := range pm.Agents {
		go func(agent Agent, taskIndex int) {
			task := subTasks[taskIndex%len(subTasks)] // 循环分配任务
			logger.Info("[PM] 分发任务给 %s: %s", agent.GetName(), task)

			// 创建Agent专用的超时上下文（比整体超时稍短）
			individualTimeout := agentTimeout - 2*time.Second
			if individualTimeout < 10*time.Second {
				individualTimeout = 10 * time.Second
			}
			agentCtx, agentCancel := context.WithTimeout(timeoutCtx, individualTimeout)
			defer agentCancel()

			// 带超时的Agent处理
			resultChan := make(chan FeedbackItem, 1)
			go func() {
				output, confidence, feedback := agent.Process(task, ctx)
				resultChan <- FeedbackItem{
					AgentName:  agent.GetName(),
					Output:     output,
					Confidence: confidence,
					Feedback:   feedback,
					Importance: 0, // 将在后续评分
				}
			}()

			select {
			case feedback := <-resultChan:
				results <- feedback
				logger.Info("[PM] 收到 %s 的反馈 (confidence: %d)", feedback.AgentName, feedback.Confidence)
			case <-agentCtx.Done():
				// Agent超时，返回错误反馈
				results <- FeedbackItem{
					AgentName:  agent.GetName(),
					Output:     fmt.Sprintf("Agent %s 处理超时", agent.GetName()),
					Confidence: 0,
					Feedback:   "处理超时",
					Importance: 0,
				}
				logger.Warn("[PM] %s 处理超时", agent.GetName())
			}
		}(agent, i)
	}

	// 收集所有结果（带超时保护）
	feedbacks := make([]FeedbackItem, 0, agentCount)
	collectTimeout := time.After(totalTimeout) // 使用配置的总超时时间

	for i := 0; i < agentCount; i++ {
		select {
		case feedback := <-results:
			feedbacks = append(feedbacks, feedback)
		case <-collectTimeout:
			// 整体超时，返回部分结果
			logger.Warn("[PM] 收集结果超时，已收集 %d/%d 个结果", len(feedbacks), agentCount)
			return feedbacks
		}
	}

	return feedbacks
}

// scoreFeedbacks 评分反馈重要度
func (pm *ProjectManager) scoreFeedbacks(feedbacks []FeedbackItem, originalTask string) []FeedbackItem {
	for i := range feedbacks {
		prompt := fmt.Sprintf(`Rate the importance of this feedback for the task: "%s"

Feedback from %s:
Output: %s
Original feedback: %s

Rate importance on a scale of 0-100, where:
- 0-30: Not important or irrelevant
- 31-70: Somewhat relevant
- 71-90: Important
- 91-100: Critical for decision making

Provide only the numerical score.`, originalTask, feedbacks[i].AgentName, feedbacks[i].Output, feedbacks[i].Feedback)

		scoreResponse, err := pm.Backend.Query(prompt, nil)
		if err != nil {
			feedbacks[i].Importance = 50 // 默认中等重要性
		} else {
			// 解析数字分数
			fmt.Sscanf(scoreResponse, "%d", &feedbacks[i].Importance)
			if feedbacks[i].Importance < 0 {
				feedbacks[i].Importance = 0
			}
			if feedbacks[i].Importance > 100 {
				feedbacks[i].Importance = 100
			}
		}

		logger.Info("[PM] %s 反馈重要性评分: %d", feedbacks[i].AgentName, feedbacks[i].Importance)
	}

	return feedbacks
}

// resolveConflicts 处理冲突和决策
func (pm *ProjectManager) resolveConflicts(feedbacks []FeedbackItem) FeedbackItem {
	if len(feedbacks) == 0 {
		return FeedbackItem{}
	}

	if len(feedbacks) == 1 {
		return feedbacks[0]
	}

	// 找到最高重要性分数的反馈
	maxImportance := 0
	bestFeedback := feedbacks[0]

	for _, feedback := range feedbacks {
		if feedback.Importance > maxImportance {
			maxImportance = feedback.Importance
			bestFeedback = feedback
		}
	}

	// 如果最高分数超过冲突阈值，直接使用
	if maxImportance >= pm.ConflictThreshold {
		logger.Info("[PM] 选择最高分反馈: %s (score: %d)", bestFeedback.AgentName, maxImportance)
		return bestFeedback
	}

	// 否则，综合所有反馈
	logger.Info("[PM] 综合所有反馈 (最高分: %d < 阈值: %d)", maxImportance, pm.ConflictThreshold)
	return pm.synthesizeFeedbacks(feedbacks)
}

// synthesizeFeedbacks 综合多个反馈
func (pm *ProjectManager) synthesizeFeedbacks(feedbacks []FeedbackItem) FeedbackItem {
	var combinedOutput, combinedFeedback string

	for _, feedback := range feedbacks {
		combinedOutput += fmt.Sprintf("\n--- %s ---\n%s\n", feedback.AgentName, feedback.Output)
		if feedback.Feedback != "" {
			combinedFeedback += fmt.Sprintf("%s: %s; ", feedback.AgentName, feedback.Feedback)
		}
	}

	// 生成综合评估
	avgConfidence := 0
	for _, feedback := range feedbacks {
		avgConfidence += feedback.Confidence
	}
	avgConfidence /= len(feedbacks)

	return FeedbackItem{
		AgentName:  "Team_Synthesis",
		Output:     fmt.Sprintf("综合团队意见:%s", combinedOutput),
		Confidence: avgConfidence,
		Feedback:   fmt.Sprintf("综合反馈: %s", combinedFeedback),
		Importance: 85, // 综合结果通常比较可靠
	}
}

// generateFinalOutput 生成最终输出
func (pm *ProjectManager) generateFinalOutput(decision FeedbackItem, originalTask string) string {
	prompt := fmt.Sprintf(`As Project Manager, create a final comprehensive output for the task: "%s"

Selected approach from %s:
%s

Provide a professional, actionable final recommendation that synthesizes the team's input.`, originalTask, decision.AgentName, decision.Output)

	finalOutput, err := pm.Backend.Query(prompt, nil)
	if err != nil {
		return fmt.Sprintf("Final output generation failed: %v\nSelected approach: %s", err, decision.Output)
	}

	return finalOutput
}

// collectTaskLogs 收集所有任务日志
func (pm *ProjectManager) collectTaskLogs() {
	pm.TaskLogs = []string{} // 清空之前的日志

	// 收集PM自己的日志
	if pm.CurrentLog != nil {
		pm.TaskLogs = append(pm.TaskLogs, pm.GenerateTaskLog())
	}

	// 收集所有子Agent的日志
	for _, agent := range pm.Agents {
		if log := agent.GetTaskLog(); log != "{}" {
			pm.TaskLogs = append(pm.TaskLogs, log)
		}
	}
}

// generateFeedbackSummary 生成反馈摘要
func (pm *ProjectManager) generateFeedbackSummary(feedbacks []FeedbackItem) string {
	if len(feedbacks) == 0 {
		return "No feedback received"
	}

	summary := fmt.Sprintf("Processed %d agent feedbacks", len(feedbacks))
	for _, feedback := range feedbacks {
		summary += fmt.Sprintf("; %s(conf:%d,imp:%d)", feedback.AgentName, feedback.Confidence, feedback.Importance)
	}

	return summary
}

// BrainstormSession 组织多Agent脑暴会议
func (pm *ProjectManager) BrainstormSession(task string) string {
	pm.mu.RLock()
	agentCount := len(pm.Agents)
	pm.mu.RUnlock()

	if agentCount == 0 {
		return "No agents available for brainstorming"
	}

	logger.Info("[PM] 开始脑暴会议，任务: %s", task)

	// 定义不同的视角
	perspectives := []string{
		"technical architecture and implementation",
		"business value and user experience",
		"risk management and scalability",
		"innovation and future-proofing",
	}

	// 收集每个Agent的脑暴结果
	type BrainstormResult struct {
		Agent       string
		Perspective string
		Idea        string
		ProsCons    map[string]string
		Scores      map[string]int
	}

	results := make([]BrainstormResult, 0, agentCount)

	// 并行执行脑暴
	resultChan := make(chan BrainstormResult, agentCount)

	for i, agent := range pm.Agents {
		go func(agent Agent, perspectiveIndex int) {
			perspective := perspectives[perspectiveIndex%len(perspectives)]
			logger.Info("[PM] %s 开始从%s视角进行脑暴", agent.GetName(), perspective)

			idea, prosCons, scores := agent.Brainstorm(task, perspective)

			resultChan <- BrainstormResult{
				Agent:       agent.GetName(),
				Perspective: perspective,
				Idea:        idea,
				ProsCons:    prosCons,
				Scores:      scores,
			}
		}(agent, i)
	}

	// 收集结果
	for i := 0; i < agentCount; i++ {
		select {
		case result := <-resultChan:
			results = append(results, result)
			logger.Info("[PM] 收到 %s 的脑暴结果", result.Agent)
		case <-time.After(time.Duration(pm.MaxFeedbackRounds*10) * time.Second):
			logger.Warn("[PM] 脑暴收集超时")
			break
		}
	}

	// 构建表格输出
	output := fmt.Sprintf("# 脑暴会议结果 - %s\n\n", task)
	output += fmt.Sprintf("参与Agent数量: %d\n", len(results))
	output += fmt.Sprintf("会议时间: %s\n\n", time.Now().Format("2006-01-02 15:04:05"))

	// 表格头部
	output += "| Agent | 视角 | 想法 | 优势 | 劣势 | 效率 | 风险 | 长效性 |\n"
	output += "|-------|------|------|------|------|------|------|--------|\n"

	// 表格内容
	for _, result := range results {
		// 截断过长的想法描述
		idea := result.Idea
		if len(idea) > 50 {
			idea = idea[:47] + "..."
		}

		pros := result.ProsCons["pros"]
		if len(pros) > 30 {
			pros = pros[:27] + "..."
		}

		cons := result.ProsCons["cons"]
		if len(cons) > 30 {
			cons = cons[:27] + "..."
		}

		output += fmt.Sprintf("| %s | %s | %s | %s | %s | %d | %d | %d |\n",
			result.Agent,
			result.Perspective,
			idea,
			pros,
			cons,
			result.Scores["efficiency"],
			result.Scores["risk"],
			result.Scores["long_term"])
	}

	// 总结部分
	output += "\n## 总结与建议\n\n"

	// 计算平均分数
	totalEfficiency := 0
	totalRisk := 0
	totalLongTerm := 0

	for _, result := range results {
		if scores := result.Scores; scores != nil {
			totalEfficiency += scores["efficiency"]
			totalRisk += scores["risk"]
			totalLongTerm += scores["long_term"]
		}
	}

	count := len(results)
	if count > 0 {
		avgEfficiency := totalEfficiency / count
		avgRisk := totalRisk / count
		avgLongTerm := totalLongTerm / count

		output += fmt.Sprintf("平均效率评分: %d/100\n", avgEfficiency)
		output += fmt.Sprintf("平均风险评分: %d/100\n", avgRisk)
		output += fmt.Sprintf("平均长效性评分: %d/100\n\n", avgLongTerm)

		// 推荐决策
		output += "### 决策建议\n"
		if avgEfficiency > 70 && avgRisk < 40 {
			output += "✅ 建议采用：整体方案可行性较高\n"
		} else if avgEfficiency > 60 && avgRisk < 60 {
			output += "⚠️ 需要权衡：方案有潜力但需谨慎评估风险\n"
		} else {
			output += "❌ 建议重新评估：当前方案存在较大风险或效率问题\n"
		}
	}

	logger.Info("[PM] 脑暴会议完成，共收集 %d 个想法", len(results))
	return output
}

// min 辅助函数
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
